<?php
/**
 * @link http://www.yiiframework.com/
 * @copyright Copyright (c) 2008 Yii Software LLC
 * @license http://www.yiiframework.com/license/
 */

namespace common\components;

use Yii;
use yii\base\InvalidConfigException;
use yii\helpers\Html;
use yii\base\Widget;
use yii\data\Pagination;
use yii\helpers\ArrayHelper;
use yii\web\JsExpression;

/**
 * LinkPager displays a list of hyperlinks that lead to different pages of target.
 *
 * LinkPager works with a [[Pagination]] object which specifies the total number
 * of pages and the current page number.
 *
 * Note that LinkPager only generates the necessary HTML markups. In order for it
 * to look like a real pager, you should provide some CSS styles for it.
 * With the default configuration, LinkPager should look good using Twitter Bootstrap CSS framework.
 *
 * For more details and usage information on LinkPager, see the [guide article on pagination](guide:output-pagination).
 *
 * @author Qiang Xue <qiang.xue@gmail.com>
 * @since 2.0
 */
class LinkPager extends \yii\widgets\LinkPager
{

    /**
     * 分页跳转指定页 label 内容 default : submit
     * @var bool
     */
    public $searchPageLabel = false;

    /**
     * 分页跳转指定页数 是否开启
     * @var bool
     */
    public $searchPage = false;

    /**
     * 分页大小 是否开启
     * @var bool
     */
    public $pageSize = false;

    /**
     * 分页跳转指定页 label CssClass
     * @var string
     */
    public $searchPageLabelCssClass = 'pageSearch';

    /**
     * pageSize list
     */
    public $pageSizeList = [10, 20, 30, 50, 100];

    /**
     * 分页跳转指定页数 a 链接 link options
     * @var array
     */
    public $searchPageLinkOptions = [
        'style' => 'float: left;'
    ];

    /**
     * pageSize style
     */
    public $pageSizeListOptions = [
        'class' => '',
        'style' => 'float: left; width: 54px; height: 34px; background: #ffffff; border:none; text-align: center; border: 1px solid #ddd; border-left: none; color: #23527c;border-radius:0px'
    ];

    /**
     * 分页跳转指定页数 options
     * @var array
     */
    public $searchPageOptions = [];

    protected $defaultSearchPageOptions = [
        'class' => '',
        'style' => 'float: left; width: 54px; height: 34px; background: #ffffff; border:none; text-align: center; border: 1px solid #ddd; border-left: none; color: #23527c;'
    ];

    /**
     * 是否开启 显示 count 总页
     * @var bool
     */
    public $pageCount = false;

    /**
     * pageCount 内容模板
     * @var string
     */
    public $pageCountContext = '共 {pageCount} 页';

    /**
     * count 总页 options
     * @var array
     */
    public $pageCountOptions = [];

    protected $defaultPageCountOptions = [
        'class' => '',
        'style' => 'float: left; height: 34px; line-height: 34px; padding: 0 15px; font-size: 14px; color: #666666;'
    ];

    /**
     * Executes the widget.
     * This overrides the parent implementation by displaying the generated page buttons.
     */
    public function run()
    {
        if ($this->registerLinkTags) {
            $this->registerLinkTags();
        }
        echo $this->renderPageButtons();
    }

    /**
     * Renders the page buttons.
     * @return string the rendering result
     */
    protected function renderPageButtons()
    {
        $pageCount = $this->pagination->getPageCount();
        if ($pageCount < 2 && $this->hideOnSinglePage) {
            return '';
        }

        $buttons = [];
        $currentPage = $this->pagination->getPage();

        // first page
        $firstPageLabel = $this->firstPageLabel === true ? '1' : $this->firstPageLabel;
        if ($firstPageLabel !== false) {
            $buttons[] = $this->renderPageButton($firstPageLabel, 0, $this->firstPageCssClass, $currentPage <= 0, false);
        }

        // prev page
        if ($this->prevPageLabel !== false) {
            if (($page = $currentPage - 1) < 0) {
                $page = 0;
            }
            $buttons[] = $this->renderPageButton($this->prevPageLabel, $page, $this->prevPageCssClass, $currentPage <= 0, false);
        }

        // internal pages
        list($beginPage, $endPage) = $this->getPageRange();
        for ($i = $beginPage; $i <= $endPage; ++$i) {
            $buttons[] = $this->renderPageButton($i + 1, $i, null, $this->disableCurrentPageButton && $i == $currentPage, $i == $currentPage);
        }

        // next page
        if ($this->nextPageLabel !== false) {
            if (($page = $currentPage + 1) >= $pageCount - 1) {
                $page = $pageCount - 1;
            }
            $buttons[] = $this->renderPageButton($this->nextPageLabel, $page, $this->nextPageCssClass, $currentPage >= $pageCount - 1, false);
        }

        // last page
        $lastPageLabel = $this->lastPageLabel === true ? $pageCount : $this->lastPageLabel;
        if ($lastPageLabel !== false) {
            $buttons[] = $this->renderPageButton($lastPageLabel, $pageCount - 1, $this->lastPageCssClass, $currentPage >= $pageCount - 1, false);
        }

        // search page
        if ($this->searchPage !== false) {
            $buttons[] = $this->renderSearchButton($this->searchPageLabel, $this->searchPage, $this->searchPageLabelCssClass);
        }

        // pageSize list
        if($this->pageSize) {
            $buttons[] = $this->renderPageSizeList();
        }

        if ($this->pageCount !== false) {
            $buttons[] = $this->renderPageCount($pageCount);
        }

        return Html::tag('ul', implode("\n", $buttons), $this->options);
    }

    /**
     * 初始化 button Options
     * @param array $options
     * @param array $linkOptions
     * @return array
     */
    protected function initOptions(array $options = [])
    {
        return  ['class' => empty($class) ?
            $this->pageCssClass :
            $class
        ];
    }

    /**
     * 渲染总页数
     * @param $pageCount
     * @return string
     */
    protected function renderPageCount($pageCount)
    {
        return  Html::tag('li', Html::tag('div', strtr($this->pageCountContext, [
            '{pageCount}' => $pageCount
        ]), array_merge($this->defaultPageCountOptions, $this->pageCountOptions)),  $this->initOptions());
    }

    protected function renderPageSizeList(){
        $pageSizeList = [];
        foreach ($this->pageSizeList as $value) {
            $pageSizeList[$value] = $value;
        }
        return Html::tag('li',
            Html::dropDownList($this->pagination->pageSizeParam, $this->pagination->getPageSize(), $pageSizeList, $this->pageSizeListOptions)
            , $this->initOptions());
    }

    /**
     * 渲染跳转指定分页框
     * @param $label
     * @param $page
     * @param $class
     * @return string
     */
    protected function renderSearchButton($label, $page, $class)
    {
        $options = $this->initOptions();
        $this->registerSearchButtonJs($funcName = $this->pagination->pageParam . 'ClickSearchButton');
        $linkOptions = empty($this->searchPageLinkOptions) ?
            $this->linkOptions :
            $this->searchPageLinkOptions;
        $linkOptions = array_merge($linkOptions, [
            'data-page' => $page,
            'onclick' => new JsExpression('javascript:' . $funcName . '.call(this);')
        ]);
        $url = $this->pagination->createUrl($page);
        return Html::tag('li',
            Html::textInput($this->pagination->pageParam, '', array_merge($this->defaultSearchPageOptions, $this->searchPageOptions)) .
            Html::a($label === false ? 'submit' : $label, $url, array_merge($linkOptions, [
                'data-href' => $url
            ])), $options);
    }

    /**
     * 注册 search button JS
     * @param $name
     */
    protected function registerSearchButtonJs($name)
    {
        $view = $this->view;
        $view->registerJs('function ' . $name . '() {
            var value = $(this).siblings("input[name=\'' . $this->pagination->pageParam . '\']").val();
            var href = $(this).attr("data-href");
            $(this).attr("href", value == "" ? "javascript:;" : href.replace(/' . $this->pagination->pageParam . '=[\s*,\d](&?)/ig, "' . $this->pagination->pageParam . '=" + value + "$1"));
        }', $view::POS_END);
    }
}